package cn.hg.jbsa.admin.provider;

import java.util.List;

import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;

import cn.hg.jboot.core.BeanStatus;
import cn.hg.jboot.core.constant.BaseConstants;
import cn.hg.jboot.core.kit.PasswordKit;
import cn.hg.jboot.core.vo.BaseResponseVo;
import cn.hg.jbsa.admin.model.JbsaAdmin;
import cn.hg.jbsa.admin.model.JbsaResource;
import cn.hg.jbsa.admin.model.JbsaRole;
import cn.hg.jbsa.admin.service.JbsaAdminService;
import cn.hg.jbsa.admin.service.JbsaResourceService;
import cn.hg.jbsa.admin.service.JbsaRoleService;
import cn.hg.jbsa.admin.service.JbsaShiroService;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import io.jboot.Jboot;
import io.jboot.aop.annotation.Bean;
import io.jboot.components.rpc.annotation.RPCBean;
import io.jboot.db.model.Columns;

/**
 * @author 胡高
 * @date 2022/04/18
 */
@Bean
@RPCBean
public class JbsaShiroServiceProvider implements JbsaShiroService {

    JbsaAdminService adminService;

    JbsaResourceService resourceService;

    JbsaRoleService roleService;

    @Override
    public AuthorizationInfo buildAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        JbsaAdmin admin = (JbsaAdmin) principals.asList().iterator().next();

        // 管理员角色
        List<JbsaRole> roleList = this.getRoleService().findByAdmin(admin);
        for (JbsaRole role : roleList) {
            String code = CharSequenceUtil.trim(role.getCode());
            if (CharSequenceUtil.isNotBlank(code)) {
                authorizationInfo.addRole(code);
            }
        }

        // 管理员操作权限
        List<JbsaResource> actionList = this.getResourceService().findActionByAdmin(admin, BeanStatus.on.name());
        for (JbsaResource jbsaResource : actionList) {
            String[] actions = CharSequenceUtil.splitToArray(jbsaResource.getValue(), '\n');
            for (String action : actions) {
                action = CharSequenceUtil.trim(action);
                if (CharSequenceUtil.isNotBlank(action)) {
                    authorizationInfo.addStringPermission(action);
                }
            }
        }

        // 管理员菜单
        // authorizationInfo.addObjectPermissions(null);;

        return authorizationInfo;
    }

    private JbsaAdminService getAdminService() {
        if (ObjectUtil.isNull(this.adminService)) {
            this.adminService = Jboot.getBean(JbsaAdminService.class);
        }

        return this.adminService;
    }

    private JbsaResourceService getResourceService() {
        if (ObjectUtil.isNull(this.resourceService)) {
            this.resourceService = Jboot.getBean(JbsaResourceService.class);
        }
        return this.resourceService;
    }

    private JbsaRoleService getRoleService() {
        if (ObjectUtil.isNull(this.resourceService)) {
            this.roleService = Jboot.getBean(JbsaRoleService.class);
        }
        return this.roleService;
    }

    @Override
    public BaseResponseVo<JbsaAdmin> shiroLogin(String userName, String password) {
        // 获取用户
        JbsaAdmin admin =
            this.getAdminService().findFirstByColumns(Columns.create("account_name", userName).ne("status", "del"));
        if (null == admin) {
            return BaseResponseVo.fail(BaseConstants.RETURN_CODE_VALUE_FAILED, "账号不存在！");
        }

        // 启动判定
        if (!"on".equals(admin.getStatus())) {
            return BaseResponseVo.fail(BaseConstants.RETURN_CODE_VALUE_FAILED, "账号已禁用，请联系管理员！");
        }

        // 密码判定
        if (!PasswordKit.validatePassword(admin.getSalt(), password, admin.getPassword())) {
            return BaseResponseVo.fail(BaseConstants.RETURN_CODE_VALUE_FAILED, "密码不正确！");
        }

        return BaseResponseVo.ok(admin);
    }

}
